# 添加必要的导入
from __future__ import annotations


from dash import Input, Output, callback_context
import plotly.graph_objects as go
from dash import Input, Output, State, callback_context, dcc, html,ctx  
import dash
import plotly.graph_objects as go
from flask_login import current_user
from sqlalchemy import and_  
# 导入地图相关函数
# from map import create_interactive_map
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from app import dash_app


from models import *

from server import server

from modules.bigscreen.callback2 import get_org_products_summary

from modules.bigscreen.charts import create_org_equipment_amount_chart,get_all_org_names,create_device_type_donut,create_device_price_donut
from modules.bigscreen.charts import get_org_running_status_list, create_org_equipment_health_chart
from modules.bigscreen.charts3 import (
    create_repair_count_chart,
    create_maintain_count_chart,
    create_inspection_count_chart
)

def register_callbacks(dash_app):
    """注册所有回调函数"""
   
    @dash_app.callback(
        [Output('big-graph-modal', 'is_open'),
        Output('big-modal-graph', 'figure')],
        [
            Input('title-org-equipment-chart', 'n_clicks'),
            Input('title-donut-panel', 'n_clicks'),
            Input('title-org-equipment-health-chart', 'n_clicks'),
            Input('title-org-equipment-repaire-count-chart', 'n_clicks'),
            Input('title-org-equipment-maintain-count-chart', 'n_clicks'),
            Input('title-org-equipment-inspection-count-chart', 'n_clicks'),
            Input('close-big-modal', 'n_clicks'),
            State('donut-type-mode', 'value'),
            State('donut-org-selector', 'value')
        ],
        prevent_initial_call=True
    )
    def show_big_graph(amount_click, donut_click, health_click, repair_click, maintain_click, inspection_click, close_click, donut_mode, donut_org):
        triggered = ctx.triggered_id
        # print(f"callbacks2 p122 triggered: {triggered}")
        # 关闭按钮优先
        if triggered == 'close-big-modal':
            return False, dash.no_update
        if triggered == 'title-org-equipment-chart' and amount_click:
            org_names, equipment_counts, total_amounts = get_org_products_summary()
            fig = create_org_equipment_amount_chart(org_names, equipment_counts, total_amounts)
            fig.update_layout(
                autosize=True,
                margin=dict(l=0, r=0, t=10, b=10)
            )
            return True, fig
        elif triggered == 'title-org-equipment-health-chart' and health_click:
            data = get_org_running_status_list()
            fig = create_org_equipment_health_chart(data)
            fig.update_layout(
                autosize=True,
                margin=dict(l=0, r=0, t=10, b=10)
            )
            return True, fig
        elif triggered == 'title-org-equipment-repaire-count-chart' and repair_click:
            fig = create_repair_count_chart()
            fig.update_layout(
                autosize=True,
                margin=dict(l=0, r=0, t=10, b=10)
            )
            return True, fig
        elif triggered == 'title-org-equipment-maintain-count-chart' and maintain_click:
            fig = create_maintain_count_chart()
            fig.update_layout(
                autosize=True,
                margin=dict(l=0, r=0, t=10, b=10)
            )
            return True, fig
        elif triggered == 'title-org-equipment-inspection-count-chart' and inspection_click:
            fig = create_inspection_count_chart()
            fig.update_layout(
                autosize=True,
                margin=dict(l=0, r=0, t=10, b=10)
            )
            return True, fig
        # print(f"callbacks2 p101 nothing happend")
        return False, dash.no_update

    
        

    @dash_app.callback(
        Output('datetime-display', 'children'),
        [Input('interval-component', 'n_intervals')]
    )
    def update_datetime(n):
        now = datetime.now()
        # 格式化时间为 YYYY-MM-DD HH:MM:SS
        formatted_time = now.strftime("%Y-%m-%d %H:%M:%S")
        return formatted_time

    
#  

    # 合并维修记录记录模态窗口的回调函数
    @dash_app.callback(
        Output('repair-records-modal', 'style'),
        [Input('repair-count-link', 'n_clicks'),
         Input('close-repair-modal', 'n_clicks')],
        prevent_initial_call=True,
        allow_duplicate=True  # 添加此参数允许重复输出
    )
    def toggle_repair_modal(open_clicks, close_clicks):
        ctx = callback_context
        if not ctx.triggered:
            return dash.no_update
            
        trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]
        
        if trigger_id == 'repair-count-link':
            print("开始执行维修记录回调")
            return {
                'display': 'flex',
                'position': 'fixed',
                'top': '0',
                'left': '0',
                'width': '100%',
                'height': '100%',
                'backgroundColor': 'rgba(0,0,0,0.7)',
                'zIndex': '1001',  # 提高层级，确保在资产统计模态窗口之上
                'justifyContent': 'center',
                'alignItems': 'center'
            }
        
        elif trigger_id == 'close-repair-modal':
            return {'display': 'none'}
            
        return dash.no_update

    # 添加获取筛选选项的回调函数
    @dash_app.callback(
        [Output('hospital-filter-dropdown', 'options'),
         Output('department-filter-dropdown', 'options'),
         Output('status-filter-dropdown', 'options')],
        Input('repair-records-modal', 'style')
    )
    def update_filter_options(modal_style):
        if modal_style.get('display') == 'flex':
            try:
                with server.app_context():
                    # 获取所有医院名称
                    hospitals = db.session.query(RepairRecords.医院名称).distinct().all()
                    hospital_options = [{'label': h[0], 'value': h[0]} for h in hospitals if h[0]]
                    
                    # 获取所有科室
                    departments = db.session.query(RepairRecords.所属科室).distinct().all()
                    department_options = [{'label': d[0], 'value': d[0]} for d in departments if d[0]]
                    
                    # 获取所有维修状态
                    statuses = db.session.query(RepairRecords.维修状态).distinct().all()
                    status_options = [{'label': s[0], 'value': s[0]} for s in statuses if s[0]]
                    
                    # 添加"全部"选项
                    hospital_options.insert(0, {'label': '全部医院', 'value': 'all'})
                    department_options.insert(0, {'label': '全部科室', 'value': 'all'})
                    status_options.insert(0, {'label': '全部状态', 'value': 'all'})
                    
                    return hospital_options, department_options, status_options
            except Exception as e:
                print(f"获取筛选选项出错: {str(e)}")
                return [{'label': '全部医院', 'value': 'all'}], [{'label': '全部科室', 'value': 'all'}], [{'label': '全部状态', 'value': 'all'}]
        
        return [{'label': '全部医院', 'value': 'all'}], [{'label': '全部科室', 'value': 'all'}], [{'label': '全部状态', 'value': 'all'}]

    # 修改生成维修记录表格的回调函数，添加筛选功能
    @dash_app.callback(
        Output('repair-records-table-container', 'children'),
        [Input('repair-records-modal', 'style'),
         Input('hospital-filter-dropdown', 'value'),
         Input('department-filter-dropdown', 'value'),
         Input('status-filter-dropdown', 'value'),
         Input('date-range-picker', 'start_date'),
         Input('date-range-picker', 'end_date')]
    )
    def update_repair_records_table(modal_style, selected_hospital, selected_department, selected_status, start_date, end_date):
        if modal_style.get('display') == 'flex':
            try:
                with server.app_context():
                    # 构建查询条件
                    query = db.session.query(RepairRecords).filter(RepairRecords.is_active == True)
                    
                    # 应用筛选条件
                    if selected_hospital and selected_hospital != 'all':
                        query = query.filter(RepairRecords.医院名称 == selected_hospital)
                    
                    if selected_department and selected_department != 'all':
                        query = query.filter(RepairRecords.所属科室 == selected_department)
                    
                    if selected_status and selected_status != 'all':
                        query = query.filter(RepairRecords.维修状态 == selected_status)
                    
                    # 应用日期范围筛选
                    if start_date:
                        query = query.filter(RepairRecords.报修时间 >= start_date)
                    
                    if end_date:
                        # 添加一天以包含结束日期当天
                        from datetime import datetime, timedelta
                        end_date_obj = datetime.strptime(end_date, '%Y-%m-%d') + timedelta(days=1)
                        query = query.filter(RepairRecords.报修时间 < end_date_obj)
                    
                    # 执行查询
                    records = query.all()
                    print(f"筛选后记录数: {len(records)}")
                    
                    # 创建表头 - 添加序号列
                    headers = ['序号', '设备名称', '医院', '科室', '通用类型', '品牌', '型号', '故障描述', '维修内容', '报修时间', '维修状态']
                    
                    # 创建表格行
                    rows = []
                    for index, record in enumerate(records, 1):  # 从1开始计数
                        row = [
                            index,  # 添加序号
                            record.设备名称 if hasattr(record, '设备名称') else '',
                            record.医院名称 if hasattr(record, '医院名称') else '',
                            record.所属科室 if hasattr(record, '所属科室') else '',
                            record.通用类型 if hasattr(record, '通用类型') else '',
                            record.品牌 if hasattr(record, '品牌') else '',
                            record.型号 if hasattr(record, '型号') else '',
                            record.故障描述 if hasattr(record, '故障描述') else '',
                            record.维修内容 if hasattr(record, '维修内容') else '',
                            record.报修时间.strftime('%Y-%m-%d %H:%M') if hasattr(record, '报修时间') and record.报修时间 else '',
                            record.维修状态 if hasattr(record, '维修状态') else '',
                        ]
                        rows.append(row)
                    
                    # 创建表格
                    table = html.Table(
                        [
                            html.Thead(
                                html.Tr([html.Th(header, style={'padding': '10px', 'backgroundColor': '#001529', 'color': 'white'}) for header in headers])
                            ),
                            html.Tbody([
                                html.Tr([
                                    html.Td(cell, style={'padding': '8px', 'borderBottom': '1px solid #333'}) 
                                    for cell in row
                                ], style={'color': 'white'})
                                for row in rows
                            ])
                        ],
                        style={
                            'width': '100%',
                            'borderCollapse': 'collapse',
                            'backgroundColor': '#002b4d'
                        }
                    )
                    
                    return table
                    
            except Exception as e:
                import traceback
                print(f"获取维修记录出错: {str(e)}")
                print(traceback.format_exc())
                return html.Div(f"加载维修记录时出错: {str(e)}", style={'color': 'red'})
        
        return html.Div()


    @dash_app.callback(
        Output('repairing-records-count', 'children'),
        Input('url', 'pathname')
    )
    def update_repairing_count(_):
        with server.app_context():
            count = db.session.query(RepairRecords).filter(
            and_(
                RepairRecords.is_active == True,
                RepairRecords.维修状态 != "已完成"
            )
        ).count()
            return str(count)

    @dash_app.callback(
        Output('repair-count-display', 'children'),
        Input('url', 'pathname')
    )
    def update_repair_count(_):
        print("开始执行维修记录统计回调")
        try:
            with server.app_context():
                print("进入应用上下文")
                # 尝试简单查询，不使用filter_by
                count = db.session.query(RepairRecords).count()
                print(f"维修记录总数: {count}")
                return str(count)
        except Exception as e:
            import traceback
            print(f"维修记录统计出错: {str(e)}")
            print(traceback.format_exc())
            return "0"

    # 显示当前登录用户名
    @dash_app.callback(
        Output('user-display', 'children'),
        [Input('url', 'pathname')]
    )
    def display_user(pathname):
        if current_user.is_authenticated:
            return f'欢迎, {current_user.realname}'
        return ''

    # 处理退出登录按钮点击
    @dash_app.callback(
        Output('url', 'pathname'),
        [Input('logout-button', 'n_clicks')],
        prevent_initial_call=True
    )
    def logout_user(n_clicks):
        if n_clicks > 0:
            # 这里不能直接调用Flask的logout_user()函数
            # 而是通过重定向到logout路由来处理
            return '/logout'


    # 控制维修统计弹窗显示
    @dash_app.callback(
        Output('maintenance-stats-modal', 'style'),
        [Input('maintenance-stats-button', 'n_clicks'),
        Input('close-maintenance-modal', 'n_clicks')],
        prevent_initial_call=True
    )
    def toggle_maintenance_modal(open_clicks, close_clicks):
        ctx = callback_context
        if ctx.triggered_id == 'maintenance-stats-button':
            return {
                'display': 'flex',
                'position': 'fixed',
                'top': '0',
                'left': '0',
                'width': '100%',
                'height': '100%',
                'backgroundColor': 'rgba(0,0,0,0.7)',
                'zIndex': '1000',
                'justifyContent': 'center',
                'alignItems': 'center'
            }
        return {'display': 'none'}

    #资产分类统计圆环图
    @dash_app.callback(
        [Output('donut-type', 'figure'),
         Output('donut-price', 'figure'),
        ],
        
        [Input('donut-org-selector', 'value'),
        Input('donut-type-mode', 'value')]
    )
    def update_donut_type(org_name, mode):
        return create_device_type_donut(org_name, mode),create_device_price_donut(org_name, mode)

    # 控制 donut_big_modal 显示/隐藏
    @dash_app.callback(
        Output('donut-big-modal', 'style'),
        [Input('title-donut-panel', 'n_clicks'),
         Input('close-donut-big-modal', 'n_clicks')],
        [State('donut-big-modal', 'style')],
        prevent_initial_call=True
    )
    def toggle_donut_big_modal(open_click, close_click, current_style):
        triggered = ctx.triggered_id
        if triggered == 'title-donut-panel':
            # 打开弹窗
            return {'display': 'flex', 'position': 'fixed', 'top': 0, 'left': 0, 'width': '100vw', 'height': '100vh',
                    'backgroundColor': 'rgba(0,0,0,0.5)', 'zIndex': 9999, 'justifyContent': 'center', 'alignItems': 'center'}
        elif triggered == 'close-donut-big-modal':
            # 关闭弹窗
            return {'display': 'none'}
        return current_style

    # 联动大圆环图下拉框
    @dash_app.callback(
        [Output('big-donut-type', 'figure'),
         Output('big-donut-price', 'figure')],
        [Input('big-donut-type-mode', 'value'),
         Input('big-donut-org-selector', 'value')]
    )
    def update_big_donut(mode, org):
        if mode is None:
            mode = 'amount'
        if org is None:
            org = 'all'
        return create_device_type_donut(org_name=org, mode=mode), create_device_price_donut(org_name=org, mode=mode)

      